<?php
/**
 * 积分商品模型
 * @author 王勇程 <laughskydragon@qq.com>
 */

namespace app\common\model;

class PointsProduct extends ModelBase
{

    
    // 自动时间戳
    protected $autoWriteTimestamp = true;
    
    // 时间字段
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    
    // 字段类型转换
    protected $type = [
        'id' => 'integer',
        'points' => 'integer',
        'stock' => 'integer',
        'sales' => 'integer',
        'sort' => 'integer',
        'status' => 'integer',
        'create_time' => 'integer',
        'update_time' => 'integer',
    ];
    
    /**
     * 获取创建时间格式化
     */
    public function getCreateTimeAttr($value)
    {
        return $value ? date('Y-m-d H:i:s', $value) : '';
    }
    
    /**
     * 获取更新时间格式化
     */
    public function getUpdateTimeAttr($value)
    {
        return $value ? date('Y-m-d H:i:s', $value) : '';
    }
    
    /**
     * 获取上架的积分商品列表
     */
    public function getActiveProducts($category = null, $paginate = false)
    {
        $where = ['status' => 1]; // 上架状态
        
        if ($category) {
            $where['category'] = $category;
        }
        
        return $this->getList($where, true, 'sort desc, id desc', $paginate);
    }
    
    /**
     * 获取热门商品
     */
    public function getHotProducts($limit = 10)
    {
        $where = ['status' => 1];
        
        return $this->getList($where, true, 'exchange_count desc, id desc', ['list_rows' => $limit]);
    }
    
    /**
     * 获取推荐商品
     */
    public function getRecommendProducts($limit = 10)
    {
        $where = ['status' => 1, 'is_recommend' => 1];
        
        return $this->getList($where, true, 'sort desc, id desc', ['list_rows' => $limit]);
    }
    
    /**
     * 按分类获取商品
     */
    public function getProductsByCategory($category, $paginate = false)
    {
        $where = ['status' => 1, 'category' => $category];
        
        return $this->getList($where, true, 'sort desc, id desc', $paginate);
    }
    
    /**
     * 获取商品分类列表
     */
    public function getCategories()
    {
        $categories = $this->getColumn(['status' => 1], 'category');
        
        return array_unique(array_filter($categories));
    }
    
    /**
     * 检查商品库存
     */
    public function checkStock($productId, $quantity = 1)
    {
        $product = $this->getInfo(['id' => $productId, 'status' => 1]);
        
        if (!$product) {
            return false;
        }
        
        return $product['stock'] >= $quantity;
    }
    
    /**
     * 扣减商品库存
     */
    public function reduceStock($productId, $quantity = 1)
    {
        $product = $this->getInfo(['id' => $productId]);
        
        if (!$product || $product['stock'] < $quantity) {
            return false;
        }
        
        return $this->updateInfo(['id' => $productId], [
            'stock' => $product['stock'] - $quantity,
            'exchange_count' => $product['exchange_count'] + $quantity,
            'update_time' => time()
        ]);
    }
    
    /**
     * 增加商品库存
     */
    public function addStock($productId, $quantity = 1)
    {
        $product = $this->getInfo(['id' => $productId]);
        
        if (!$product) {
            return false;
        }
        
        return $this->updateInfo(['id' => $productId], [
            'stock' => $product['stock'] + $quantity,
            'update_time' => time()
        ]);
    }
    
    /**
     * 更新商品兑换次数
     */
    public function updateExchangeCount($productId, $count = 1)
    {
        return $this->updateInfo(['id' => $productId], [
            'exchange_count' => ['inc', $count],
            'update_time' => time()
        ]);
    }
    
    /**
     * 获取商品统计信息
     */
    public function getProductStats($productId = null)
    {
        $where = ['status' => 1];
        
        if ($productId) {
            $where['id'] = $productId;
        }
        
        $totalProducts = $this->stat($where, 'count');
        $totalStock = $this->getValue($where, 'SUM(stock)') ?: 0;
        $totalExchanged = $this->getValue($where, 'SUM(exchange_count)') ?: 0;
        $totalPoints = $this->getValue($where, 'SUM(points * exchange_count)') ?: 0;
        
        return [
            'total_products' => $totalProducts,
            'total_stock' => $totalStock,
            'total_exchanged' => $totalExchanged,
            'total_points' => $totalPoints
        ];
    }
    
    /**
     * 搜索商品
     */
    public function searchProducts($keyword, $paginate = false)
    {
        $where = [
            'status' => 1,
            'name' => ['like', "%{$keyword}%"]
        ];
        
        return $this->getList($where, true, 'sort desc, id desc', $paginate);
    }
    
    /**
     * 获取积分范围内的商品
     */
    public function getProductsByPointsRange($minPoints, $maxPoints, $paginate = false)
    {
        $where = [
            'status' => 1,
            'points' => ['between', [$minPoints, $maxPoints]]
        ];
        
        return $this->getList($where, true, 'points asc, id desc', $paginate);
    }
    
    /**
     * 获取库存不足的商品
     */
    public function getLowStockProducts($threshold = 10)
    {
        $where = [
            'status' => 1,
            'stock' => ['<=', $threshold]
        ];
        
        return $this->getList($where, true, 'stock asc, id desc');
    }
    
    /**
     * 批量更新商品状态
     */
    public function batchUpdateStatus($productIds, $status)
    {
        $where = ['id' => ['in', $productIds]];
        
        return $this->updateInfo($where, [
            'status' => $status,
            'update_time' => time()
        ]);
    }
    
    /**
     * 获取商品兑换排行
     */
    public function getExchangeRanking($limit = 10, $startTime = null, $endTime = null)
    {
        $where = ['status' => 1];
        
        if ($startTime || $endTime) {
            // 如果有时间限制，需要关联积分记录表来统计
            $sql = "SELECT p.id, p.name, p.points, p.images, COUNT(pr.id) as exchange_count
                    FROM {$this->getTable()} p
                    LEFT JOIN " . (new PointsRecord())->getTable() . " pr ON pr.extra_data LIKE CONCAT('%\"product_id\":', p.id, '%')
                    WHERE p.status = 1 AND pr.type = 'exchange'";
            
            $params = [];
            if ($startTime) {
                $sql .= " AND pr.create_time >= ?";
                $params[] = $startTime;
            }
            if ($endTime) {
                $sql .= " AND pr.create_time <= ?";
                $params[] = $endTime;
            }
            
            $sql .= " GROUP BY p.id ORDER BY exchange_count DESC LIMIT {$limit}";
            
            return \think\facade\Db::query($sql, $params);
        } else {
            // 直接使用商品表的兑换次数
            return $this->getList($where, 'id,name,points,images,exchange_count', 'exchange_count desc', ['list_rows' => $limit]);
        }
    }
    
    /**
     * 清理下架商品
     */
    public function cleanOfflineProducts($days = 30)
    {
        $expireTime = time() - ($days * 86400);
        $where = [
            'status' => 0,
            'update_time' => ['<', $expireTime]
        ];
        
        return $this->deleteInfo($where);
    }
}